#pragma once

#include <string>
#include <vector>
#include <utility>
#include <opencv2/opencv.hpp>

namespace protonet {

/**
 * @brief IPU图像预处理器类
 * 根据提供的预处理配置进行图像预处理
 */
class IPUImagePreprocessor {
public:
    /**
     * @brief 预处理配置结构体
     */
    struct PreprocessConfig {
        std::string input_format = "BGR";           ///< 输入格式
        int resize_height = 224;                    ///< 目标高度
        int resize_width = 224;                     ///< 目标宽度
        bool do_normalize = true;                   ///< 是否归一化
        bool to_rgb = false;                        ///< 是否转换为RGB
        bool to_nchw = false;                       ///< 是否转换为NCHW格式
        std::string norm_scheme = "subtract_first"; ///< 归一化方案
        std::vector<float> mean_values = {123.675f, 116.28f, 103.53f};  ///< 均值(BGR顺序)
        std::vector<float> std_values = {58.395f, 57.12f, 57.375f};     ///< 标准差(BGR顺序)
    };
    
    /**
     * @brief 构造函数
     * @param target_size 目标图像尺寸
     * @param config 预处理配置，如果为空则使用默认配置
     */
    IPUImagePreprocessor(const std::pair<int, int>& target_size = {224, 224},
                        const PreprocessConfig* config = nullptr);
    
    /**
     * @brief 析构函数
     */
    ~IPUImagePreprocessor() = default;
    
    /**
     * @brief 禁用拷贝构造和赋值
     */
    IPUImagePreprocessor(const IPUImagePreprocessor&) = delete;
    IPUImagePreprocessor& operator=(const IPUImagePreprocessor&) = delete;
    
    /**
     * @brief 设置目标尺寸
     * @param target_size 目标尺寸
     */
    void setTargetSize(const std::pair<int, int>& target_size);
    
    /**
     * @brief 预处理图像
     * @param image_path 图像文件路径
     * @return 预处理后的数据向量（NHWC格式）
     */
    std::vector<float> preprocessImage(const std::string& image_path);
    
    /**
     * @brief 预处理图像（从cv::Mat）
     * @param image OpenCV图像矩阵
     * @return 预处理后的数据向量（NHWC格式）
     */
    std::vector<float> preprocessImage(const cv::Mat& image);
    
    /**
     * @brief 获取目标尺寸
     * @return 目标尺寸
     */
    std::pair<int, int> getTargetSize() const { return target_size_; }

private:
    std::pair<int, int> target_size_;       ///< 目标图像尺寸
    PreprocessConfig config_;               ///< 预处理配置
    
    /**
     * @brief 执行图像预处理的核心逻辑
     * @param image 输入图像
     * @return 预处理后的数据向量
     */
    std::vector<float> processImage(cv::Mat image);
    
    /**
     * @brief 应用归一化
     * @param image 输入图像
     * @return 归一化后的图像
     */
    cv::Mat applyNormalization(const cv::Mat& image);
    
    /**
     * @brief 转换颜色格式
     * @param image 输入图像
     * @return 转换后的图像
     */
    cv::Mat convertColorFormat(const cv::Mat& image);
    
    /**
     * @brief 转换数据布局
     * @param data 输入数据（HWC格式）
     * @param height 图像高度
     * @param width 图像宽度
     * @param channels 图像通道数
     * @return 转换后的数据（NCHW格式）
     */
    std::vector<float> convertToNCHW(const std::vector<float>& data, 
                                    int height, int width, int channels);
};

} // namespace protonet